#pragma once

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFileDialog>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
    , m_bIsOpen(false)
    , m_bIsSnap(false)
{
    ui->setupUi(this);

    ui->statusbar->showMessage("欢迎使用大恒相机[for Qt]");

    m_pBitmap = ui->widget;
    LabelShowCurImg = ui->label_CurInput;
    imageView = ui->ImageView;

    connect(ui->spinBox,&QSpinBox::valueChanged,ui->horizontalSlider,&QSlider::setValue);
    connect(ui->horizontalSlider,&QSlider::valueChanged,ui->spinBox,&QSpinBox::setValue);
    connect(ui->spinBox_gain,&QSpinBox::valueChanged,ui->horizontalSlider_gain,&QSlider::setValue);
    connect(ui->horizontalSlider_gain,&QSlider::valueChanged,ui->spinBox_gain,&QSpinBox::setValue);

    //大恒API库调用
    try
    {
        //初始化设备
        IGXFactory::GetInstance().Init();

        m_pCaptureEventHandler = new CSampleCaptureEventHandler();

        //更新界面
        UpdateUI();
    }
    catch (CGalaxyException& e)
    {
        if (m_pCaptureEventHandler != NULL)
        {
            delete m_pCaptureEventHandler;
            m_pCaptureEventHandler = NULL;
        }
        ui->statusbar->showMessage(QString::fromStdString(e.what()));

        return;

    }
    catch (std::exception& e)
    {
        if (m_pCaptureEventHandler != NULL)
        {
            delete m_pCaptureEventHandler;
            m_pCaptureEventHandler = NULL;
        }

        ui->statusbar->showMessage(QString::fromStdString(e.what()));
        return;

    }
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::UpdateUI()
{
    ui->pushButton_OpenCam->setEnabled(!m_bIsOpen);
    ui->pushButton_CloseCam->setEnabled(m_bIsOpen);
    ui->pushButton_StartGrab->setEnabled(m_bIsOpen && !m_bIsSnap);
    ui->pushButton_StopGrab->setEnabled(m_bIsOpen && m_bIsSnap);
}


void MainWindow::on_pushButton_OpenCam_clicked()
{
    bool bIsDeviceOpen = false;		//设备是否打开标识
    bool bIsStreamOpen = false;		//设备流是否打开标识
    try
    {
        //枚举设备
        GxIAPICPP::gxdeviceinfo_vector vectorDeviceInfo;
        IGXFactory::GetInstance().UpdateDeviceList(1000, vectorDeviceInfo);

        if (vectorDeviceInfo.size() == 0)
        {
            m_bIsOpen = false;
            bIsDeviceOpen = false;
            ui->statusbar->showMessage("无可用设备！");
            return;
        }

        //打开第一个设备以及设备下面第一个流
        m_ObjDevicePtr = IGXFactory::GetInstance().OpenDeviceBySN(vectorDeviceInfo[0].GetSN(), GX_ACCESS_EXCLUSIVE);//打开方式：独占
        m_bIsOpen = true;
        bIsDeviceOpen = true;

        //获取远端设备属性控制器
        m_ObjFeatureControlPtr = m_ObjDevicePtr->GetRemoteFeatureControl();

        //为Mat矩阵开辟空间
        AllocateRoomForMatCurImgPtr();

        //为画图对象分配设备指针
        m_pBitmap->addDevicePtr(m_ObjDevicePtr);

        //判断设备流是否大于零，如果大于零则打开流
        int nStreamCount = m_ObjDevicePtr->GetStreamCount();

        if (nStreamCount)
        {
            m_ObjStreamPtr = m_ObjDevicePtr->OpenStream(0);
            //获取流层属性控制器
            m_ObjStreamFeatureControlPtr = m_ObjStreamPtr->GetFeatureControl();
            bIsStreamOpen = true;
        }
        else
        {
            throw exception("未发现设备流！");
        }

        //更新界面
        UpdateUI();

        ui->statusbar->showMessage(QString("打开设备成功！"));
    }
    catch (CGalaxyException& e)
    {
        //判断设备流是否已打开
        if (bIsStreamOpen)
        {
            m_ObjStreamPtr->Close();
        }

        //判断设备是否已打开
        if (bIsDeviceOpen)
        {
            m_ObjDevicePtr->Close();
        }

        ui->statusbar->showMessage(QString::fromStdString(e.what()));

        return;
    }
    catch (exception& e)
    {
        //判断设备流是否已打开
        if (bIsStreamOpen)
        {
            m_ObjStreamPtr->Close();
        }

        //判断设备是否已打开
        if (bIsDeviceOpen)
        {
            m_ObjDevicePtr->Close();
        }

        ui->statusbar->showMessage(QString::fromStdString(e.what()));
        return;
    }
}


void MainWindow::on_pushButton_CloseCam_clicked()
{
    try
    {
        //判断是否已停止采集
        if (m_bIsSnap)
        {
            //发送停采命令
            m_ObjFeatureControlPtr->GetCommandFeature("AcquisitionStop")->Execute();

            //关闭流层采集
            m_ObjStreamPtr->StopGrab();

            //注销采集回调
            m_ObjStreamPtr->UnregisterCaptureCallback();
        }
    }
    catch (CGalaxyException)
    {
        //do noting
    }

    try
    {
        //关闭流对象
        m_ObjStreamPtr->Close();

    }
    catch (CGalaxyException)
    {
        //do noting
    }
    try
    {
        //关闭设备
        m_ObjDevicePtr->Close();
        ui->statusbar->showMessage(QString("关闭设备成功！"));
    }
    catch (CGalaxyException)
    {
        //do noting
    }

    m_bIsOpen = false;
    m_bIsSnap = false;

    //更新界面
    UpdateUI();
}


void MainWindow::on_pushButton_StartGrab_clicked()
{
    // TODO: Add your control notification handler code here
    try
    {
        try
        {
            //设置Buffer处理模式
            m_ObjStreamFeatureControlPtr->GetEnumFeature("StreamBufferHandlingMode")->SetValue("OldestFirst");
        }
        catch (...)
        {
        }

        //注册回调函数
        m_ObjStreamPtr->RegisterCaptureCallback(m_pCaptureEventHandler, this);

        //开启流层通道
        m_ObjStreamPtr->StartGrab();

        //发送开采命令
        m_ObjFeatureControlPtr->GetCommandFeature("AcquisitionStart")->Execute();
        m_bIsSnap = true;

        //更新界面
        UpdateUI();
        ui->statusbar->showMessage(QString("开始采集！"));
    }
    catch (CGalaxyException& e)
    {
        ui->statusbar->showMessage(QString::fromStdString(e.what()));

        return;
    }
    catch (std::exception& e)
    {
        ui->statusbar->showMessage(QString::fromStdString(e.what()));

        return;
    }
}


void MainWindow::on_pushButton_StopGrab_clicked()
{
    // TODO: Add your control notification handler code here
    try
    {
        //发送停采命令
        m_ObjFeatureControlPtr->GetCommandFeature("AcquisitionStop")->Execute();

        //关闭流层通道
        m_ObjStreamPtr->StopGrab();

        //注销采集回调
        m_ObjStreamPtr->UnregisterCaptureCallback();
        m_bIsSnap = false;

        //更新界面
        UpdateUI();
        ui->statusbar->showMessage(QString("停止采集！"));

    }
    catch (CGalaxyException& e)
    {
        ui->statusbar->showMessage(QString::fromStdString(e.what()));

        return;
    }
    catch (std::exception& e)
    {
        ui->statusbar->showMessage(QString::fromStdString(e.what()));

        return;
    }
}


void MainWindow::on_pb_setExp_clicked()
{
    float ParmsExposureTime = (ui->spinBox->text()).toFloat();
    ParmsExposureTime = ParmsExposureTime > 20 ? ParmsExposureTime : 20;
    m_ObjFeatureControlPtr->GetFloatFeature("ExposureTime")->SetValue(ParmsExposureTime);
    //设置增益
    float ParmsFps = ui->spinBox_gain->value();
//    ParmsFps = ParmsFps > 0.1 ? ParmsFps : 0.1;
    m_ObjFeatureControlPtr->GetFloatFeature("Gain")->SetValue(ParmsFps);
}


/* **************************************Opencv函数设计***********************************************/
//打开相机时调用此函数获得图片基本信息
void MainWindow::AllocateRoomForMatCurImgPtr()
{
    m_ObjFeatureControlPtr = m_ObjDevicePtr->GetRemoteFeatureControl();
    CIntFeaturePointer ObjIntPtrWidth = m_ObjFeatureControlPtr->GetIntFeature("AAROIWidth");
    CIntFeaturePointer ObjIntPtrHeight = m_ObjFeatureControlPtr->GetIntFeature("AAROIHeight");
    ImgWidth = ObjIntPtrWidth->GetValue();//获取图片宽
    ImgHeight = ObjIntPtrHeight->GetValue();//获取图片高
    CurImgMat.create(ImgHeight, ImgWidth, CV_8UC1);//为Mat矩阵开辟空间
}

//连续采集绘图设备
void MainWindow::ShowCurImgInLabel(QLabel* ptrLabelToShow, cv::Mat& CVMat)
{
    //获取要显示图片的label的大小
    QSize LabelSize = ptrLabelToShow->size();
    QImage QSrcImg = CV2QTFORMAT::cvMatToQImage(CVMat);//获取一个QImage
    QSrcImg = QSrcImg.scaled(LabelSize, Qt::KeepAspectRatio,Qt::SmoothTransformation);//重新调整图像大小以适应窗口
    ptrLabelToShow->setPixmap(QPixmap::fromImage(QSrcImg));//显示
}

void MainWindow::ShowCurImgInImgView(MyImageView* imgView, cv::Mat& CVMat)
{
    QImage myImage;
    myImage = QImage((const unsigned char*)(CVMat.data),CVMat.cols,CVMat.rows,QImage::Format_RGB888);
    if(myImage.isNull())
    {
        ui->statusbar->showMessage("newPixmap is a null image!");
        return;
    }
    imgView->showImage(myImage);
}

void MainWindow::on_pushButton_GetImg_clicked()
{

    QString filePath = QFileDialog::getOpenFileName(this,
                                                         tr("打开图像"),tr(""),
                                                         tr("png文件 (*.png);;""jpg文件 (*.jpg);;""bmp文件(*.bmp)"));
    Mat img = imread(filePath.toLocal8Bit().constData());
//    cv::imshow("Image", img);
//    cv::waitKey(0);
//    cv::destroyAllWindows();
    ShowCurImgInImgView(imageView,img);
}


void MainWindow::on_pushButton_SingleGrab_clicked()
{
    /*CGXStreamPointer objStreamPtr = m_ObjDevicePtr->OpenStream(0);
    objStreamPtr->StartGrab();

    //给设备发送开采命令
    CGXFeatureControlPointer objFeatureControlPtr =
                                            m_ObjDevicePtr->GetRemoteFeatureControl();
    objFeatureControlPtr->GetCommandFeature("AcquisitionStart")->Execute();

    //采单帧
    CImageDataPointer objImageDataPtr;
    objImageDataPtr = objStreamPtr->GetImage(500);//超时时间使用500ms，用户可以自行设定
    if (objImageDataPtr->GetStatus() == GX_FRAME_STATUS_SUCCESS)
    {
     //采图成功而且是完整帧，可以进行图像处理...
//        MainWindow* CamUiPtr = (MainWindow*)pUserParam;
        //以下为连续采集部分的显示
//        void* pRaw8Buffer = NULL;
//        pRaw8Buffer = objImageDataPtr->ConvertToRaw8(GX_BIT_0_7);
//        std::memcpy(CamUiPtr->CurImgMat.data, pRaw8Buffer, (objImageDataPointer->GetHeight()) * (objImageDataPointer->GetWidth()));
        m_pBitmap->Show(objImageDataPtr);
    }

    //停采
    objFeatureControlPtr->GetCommandFeature("AcquisitionStop")->Execute();
    objStreamPtr->StopGrab();

    //关闭流通道
    objStreamPtr->Close();*/
}

